﻿#pragma once

#include <Logger.h>
#include <FixBuffer.h>
#include <LogFile.h>
#include <CountDownLatch.h>
#include <string>
#include <atomic>
#include <functional>
#include <vector>
#include <thread>

namespace AsyncLogger {

	class AsyncLogger {
		using Buffer = detail::FixBuffer<detail::kLargeBuffer>;
		using BufferVec = std::vector < std::unique_ptr<Buffer>>;
		using BufferPtr = BufferVec::value_type;
	public:
		AsyncLogger(const std::string& logDir,
			const std::string& basename,
			off_t rollSize,
			int flushInterval = 3);

		void append(const char* logline, size_t len);

		void start();

		void stop();

		~AsyncLogger();
	private:
		void asyncLogThread();

	private:
		std::atomic<bool> isRunning_;
		CountDownLatch latch_;
		off_t rollSize_;
		int count_;
		const int flushInterval_;
		const std::string logDir_;
		const std::string basename_;
		std::unique_ptr<std::thread> logThread_;
		std::mutex mutex_;
		std::condition_variable condition_;
		LogFile output_;

		BufferVec buffers_;
		BufferPtr currBuffer_;
		BufferPtr nextBuffer_;
	};
}